<template>
  <div class="rule">
    <el-form ref="ruleFormRef" style="max-width: 600px" :model="ruleForm" status-icon :rules="rules" label-width="auto"
      class="demo-ruleForm">
      <el-form-item label="密码" prop="pass">
        <el-input v-model="ruleForm.pass" type="password" />
      </el-form-item>
      <el-form-item label="确认密码" prop="checkPass">
        <el-input v-model="ruleForm.checkPass" type="password" />
      </el-form-item>
      <el-form-item label="年龄" prop="age">
        <el-input v-model.number="ruleForm.age" />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="submitForm(ruleFormRef)">Submit</el-button>
        <el-button @click="resetForm(ruleFormRef)">Reset</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script setup lang="ts">
import { reactive, ref } from 'vue'
import type { FormInstance, FormRules } from 'element-plus'

const ruleFormRef = ref<FormInstance>()

//自定义的年龄校验规则
//rule:规则 value：校验的值 callback：回调方法
const checkAge = (rule: any, value: any, callback: any) => {
  if (!value) {//如果输入的年龄不存在
    //那么就返回一个回调方法，传递一个报错对象及报错信息
    return callback(new Error('请输入年龄'))
  }
  //  延时器 - 1秒之后只执行一次
  setTimeout(() => {
    if (!Number.isInteger(value)) { // 判断输入的年龄是否是数字整形，如果不是
      //回调一个报错对象及报错信息
      callback(new Error('请输入数字整数'))
    } else {
      //如果是正整数，那么接着判断
      if (value < 18) {
        //如果输入的年龄小于18岁，回调一个报错信息
        callback(new Error('输入的年龄必须大于18岁'))
      } else {
        callback()
      }
    }
  }, 1000)
}

const validatePass = (rule: any, value: any, callback: any) => {
  if (value === '') {
    callback(new Error('请输入密码'))
  } else {
    if (ruleForm.checkPass !== '') {//如果确认密码不为空字符串
      if (!ruleFormRef.value) return//如果表单组件元素不存在，直接结束
      //如果存在，做密码校验
      ruleFormRef.value.validateField('checkPass', () => null)
    }
    //成功回调
    callback()
  }
}
//校验确认密码
const validatePass2 = (rule: any, value: any, callback: any) => {
  if (value === '') {
    callback(new Error('请输入确认密码'))
  } else if (value !== ruleForm.pass) {
    callback(new Error("请输入相同的确认密码"))
  } else {
    callback()
  }
}
//表单数据对象
const ruleForm = reactive({
  pass: '',
  checkPass: '',
  age: '',
})
//自定义配置校验规则
const rules = reactive<FormRules<typeof ruleForm>>({
  //密码的校验
  //validator:自定义的校验密码的方法名称
  pass: [{ required: true, validator: validatePass, trigger: 'blur' }],
  //确认密码的校验
  checkPass: [{ required: true, validator: validatePass2, trigger: 'blur' }],
  //年龄的校验
  age: [{ required: true, validator: checkAge, trigger: 'blur' }],
})
//表单的提交
const submitForm = (formEl: FormInstance | undefined) => {
  if (!formEl) return
  formEl.validate((valid) => {
    if (valid) {
      console.log('submit!')
    } else {
      console.log('error submit!')
      return false
    }
  })
}

const resetForm = (formEl: FormInstance | undefined) => {
  if (!formEl) return
  formEl.resetFields()
}
</script>

<style lang="less" scoped></style>